﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Web;
using CsQuery;
using DataLayer.Entities;
using DataLayer.Implementations;
using DonutMgmtSystemFoundation.Models;
using DonutMgmtSystemFoundation.Models.JqGridModel;
using ViewRes;

namespace DonutMgmtSystemFoundation.Helpers
{
    public class AdminHelper
    {
        #region Donut catalog
        public GeneralJsonResultModel UpdateDonutsCatalog()
        {
            try
            {
                List<Donut> donuts = GetDonutsFromSite();
                DonutApplication dApp = new DonutApplication();

                // Save new donuts
                foreach (Donut donut in donuts)
                {
                    Donut donutFromDb = dApp.GetByDonutUniqueName(donut.UniqueName);
                    if (donutFromDb == null)
                    {
                        dApp.Save(donut);
                    }
                    else if (!donutFromDb.IsActive)
                    {
                        donutFromDb.IsActive = true;
                        dApp.Save(donutFromDb);
                    }
                }

                // Deactivate old donuts
                foreach (Donut donutFromDb in dApp.GetAll())
                {
                    Donut donut = (from d in donuts
                                   where d.UniqueName == donutFromDb.UniqueName
                                   select d).FirstOrDefault();
                    if (donut == null)
                    {
                        donutFromDb.IsActive = false;
                        dApp.Save(donutFromDb);
                    }
                }

                return new GeneralJsonResultModel(true, Admin.UpdateCatOk);
            }
            catch
            {
                return new GeneralJsonResultModel(false, Admin.UpdateCatError);
            }
        }

        private List<Donut> GetDonutsFromSite()
        {
            var dom = CQ.CreateFromUrl(ConfigurationManager.AppSettings["DonutsCatalogUrl"]);
            string prefixUrl = ConfigurationManager.AppSettings["DonutsPrefixUrl"];
            var items = dom["div.slide"];
            List<Donut> donuts = new List<Donut>();
            foreach (var donutDiv in items)
            {
                Donut donut = new Donut();
                donut.IsActive = true;
                // Agregar Url
                string url = donutDiv.Attributes["src"].ToString();
                donut.Url = String.Format("{0}{1}", prefixUrl, url);
                donut.UniqueName = url.Substring(url.LastIndexOf("/") + 1, url.Length - url.LastIndexOf("/") - 5);

                var text_wrapper = (from elems in donutDiv.ChildElements
                                    where elems.ClassName == "text_wrapper"
                                    select elems).FirstOrDefault();
                if (text_wrapper != null)
                {
                    var title = (from div in text_wrapper.ChildElements
                                 where div.ClassName == "title"
                                 select div).FirstOrDefault();
                    var description = (from div in text_wrapper.ChildElements
                                       where div.ClassName == "des"
                                       select div).FirstOrDefault();

                    if (title != null && description != null)
                    {
                        donut.Description = HttpUtility.HtmlDecode(description.InnerText);
                        donut.Name = title.InnerHTML;
                        donuts.Add(donut);
                    }
                }
            }

            return donuts;
        }
        #endregion

        #region Users activation
        public List<UserAdminActivationModel> GetActivationUsers()
        {
            UserApplication app = new UserApplication();
            List<User> users = (List<User>)app.GetUsersToActivate();

            List<UserAdminActivationModel> list = new List<UserAdminActivationModel>();

            foreach (User user in users)
            {
                list.Add(new UserAdminActivationModel()
                {
                    UserId = user.UserId.Value,
                    Name = user.Name,
                    Email = user.Email,
                    Approved = user.ApprovedByAdmin
                });
            }

            return list;
        }

        public GeneralJsonResultModel ActivateUser(int userId)
        {
            try
            {
                UserApplication app = new UserApplication();
                User user = app.GetById(userId);

                user.ApprovedByAdmin = true;
                app.Save(user);

                UserOrderApplication uoApp = new UserOrderApplication();
                UserOrder uo = uoApp.GetByUserId(userId);
                if (uo == null)
                {
                    uo = new UserOrder()
                    {
                        User = user,
                        OrderNumber = uoApp.GetNextUserOrder()
                    };

                    uoApp.Save(uo);
                }

                return new GeneralJsonResultModel(true, Admin.UserActivatedOk);
            }
            catch
            {
                return new GeneralJsonResultModel(false, Admin.UserActivatedError);
            }
        }

        public GeneralJsonResultModel DeactivateUser(int userId)
        {
            try
            {
                UserApplication app = new UserApplication();
                User user = app.GetById(userId);

                user.ApprovedByAdmin = false;
                app.Save(user);

                return new GeneralJsonResultModel(true, Admin.UserDeactivatedOk);
            }
            catch
            {
                return new GeneralJsonResultModel(false, Admin.UserDeactivatedError);
            }
        }
        #endregion

        #region Members

        public JqGridModel GetMembers(JqGridRequest jQreq)
        {
            UserApplication app = new UserApplication();

            string orderBy = jQreq.sidx;
            string asc = jQreq.sord;
            List<User> users = (List<User>)app.GetAll(orderBy, asc == "asc");

            JqGridModel model = new JqGridModel();

            if (users != null)
            {
                model.records = users.Count;
                int totalPages = users.Count / jQreq.rows;
                model.total = totalPages < 1 ? 1: totalPages;
                model.page = jQreq.page;

                // Paging and sorting
                var queryResultPage = users
                      .Skip(jQreq.rows * (jQreq.page - 1))
                      .Take(jQreq.rows);
                users = queryResultPage.ToList();

                List<JqGridCell> rows = new List<JqGridCell>();
                foreach (User user in users)
                {
                    JqGridCell row = new JqGridCell();
                    row.id = user.UserId.Value;
                    List<object> data = new List<object>();
                    data.Add(user.UserId);
                    data.Add(user.Name);
                    data.Add(user.Email);
                    data.Add(user.Username);
                    data.Add(user.Role.Name);
                    data.Add(user.IsActive);
                    row.cell = data;

                    rows.Add(row);
                }

                model.rows = rows;
            }

            return model;
        }

        public GeneralJsonResultModel SaveMember(User user, int userId, int role)
        {
            try
            {
                UserApplication app = new UserApplication();

                User dbUser = app.GetById(userId);
                dbUser.Email = user.Email;
                dbUser.Username = user.Username;
                dbUser.Name = user.Name;
                dbUser.ModifiedDate = DateTime.Now;
                dbUser.IsActive = user.IsActive;
                dbUser.Role = new Role() { RoleId = role };

                app.Save(dbUser);

                return new GeneralJsonResultModel(true, Admin.MsgSavedOk);
            }
            catch
            {
                return new GeneralJsonResultModel(true, Admin.MsgSavedError);
            }
        }

        #endregion

        #region Send mails

        public SendMailModel GetDefaultMailModels()
        {
            // Para pagos
            CalendarHelper calendar = new CalendarHelper();
            
            string emailsToPay = string.Empty;
            int usersPerDay = Int32.Parse(ConfigurationManager.AppSettings["UsersPerDay"]);
            int daysUntilFriday = ((int)DayOfWeek.Friday - (int)DateTime.Today.DayOfWeek + 7) % 7;
            DateTime nextFriday = DateTime.Today.AddDays(daysUntilFriday);

            List<CalendarEventModel> events = calendar.GetEvents();
            events = (from e in events
                      where e.start == nextFriday.ToString("yyyy-MM-dd hh:mm:ss")
                      select e
                      ).ToList();

            foreach (CalendarEventModel event_ in events)
            {
                emailsToPay += event_.Email + "; ";
            }
            
            MailModel paymentModel = new MailModel()
            {
                To = emailsToPay,
                Bcc = ConfigurationManager.AppSettings["BccMail"],
                Subject = Admin.PaymentDonuts
            };

            // Para cuando llegan las donas
            UserOrderApplication userApp = new UserOrderApplication();
            IList<UserOrder> users = userApp.GetActiveUsersOrderedByUserOrder();
            string emailsToNotify = string.Empty;

            foreach (UserOrder userOrder in users)
            {
                emailsToNotify += userOrder.User.Email + "; ";
            }

            MailModel arrivedModel = new MailModel()
            {
                To = emailsToNotify,
                Bcc = ConfigurationManager.AppSettings["BccMail"],
                Subject = Admin.ArrivedSubject
            };

            // Para pedido
            MailModel orderModel = new MailModel()
            {
                To = ConfigurationManager.AppSettings["OrderTo"],
                Bcc = ConfigurationManager.AppSettings["BccMail"],
            };

            SendMailModel m = new SendMailModel();
            m.Payment = paymentModel;
            m.Remainder = arrivedModel;
            m.Order = orderModel;

            return m;
        }

        private string GetNewLines(int quantity)
        {
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < quantity; i++)
            {
                builder.Append(System.Environment.NewLine);
            }
            return builder.ToString();
        }

        public GeneralJsonResultModel SendPaymentMail(MailModel model)
        {
            try
            {
                MailerHelper mailHelper = new MailerHelper();

                mailHelper.SendPayment(model).Send();

                return new GeneralJsonResultModel(true, Admin.MsgSentOk);
            }
            catch
            {
                return new GeneralJsonResultModel(false, Admin.MsgSentError);
            }
        }

        public GeneralJsonResultModel SendDonutsArrivedMail(MailModel model)
        {
            try
            {
                MailerHelper mailHelper = new MailerHelper();

                mailHelper.SendDonutsArrived(model).Send();

                return new GeneralJsonResultModel(true, Admin.MsgSentOk);
            }
            catch
            {
                return new GeneralJsonResultModel(false, Admin.MsgSentError);
            }
        }

        public GeneralJsonResultModel SendOrderMail(MailModel model)
        {
            try
            {
                model.Subject = "Pedido de HCL";
                MailerHelper mailHelper = new MailerHelper();
                DonutsHelper helper = new DonutsHelper();
                CalendarHelper calendar = new CalendarHelper();
                List<CalendarEventModel> events = calendar.GetEvents();
                DateTime nextDate = DateTime.Today;
                int daysUntilFriday = ((int)DayOfWeek.Friday - (int)DateTime.Today.DayOfWeek + 7) % 7;
                DateTime nextFriday = DateTime.Today.AddDays(daysUntilFriday);

                List<UserDonutsModel> mailModel = helper.GetUsersDonuts();
                mailHelper
                    .SendOrder(model, mailModel, nextFriday)
                    .Send();

                return new GeneralJsonResultModel(true, Admin.MsgSentOk);
            }
            catch
            {
                return new GeneralJsonResultModel(false, Admin.MsgSentError);
            }
        }

        #endregion
    }
}